#ifndef DIO_REQUEST_OPERATIONS_H_
#define DIO_REQUEST_OPERATIONS_H_

#include <fermat/dio/iostats.h>
#include <fermat/dio/request.h>

namespace fermat {

template <typename RequestIterator>
void wait_all(RequestIterator reqs_begin, RequestIterator reqs_end) {
    for ( ; reqs_begin != reqs_end; ++reqs_begin)
        (RequestPtr(*reqs_begin))->wait();
}

static inline void wait_all(RequestPtr req_array[], size_t count) {
    wait_all(req_array, req_array + count);
}

template <typename RequestIterator>
typename std::iterator_traits<RequestIterator>::difference_type
cancel_all(RequestIterator reqs_begin, RequestIterator reqs_end) {
    typename std::iterator_traits<RequestIterator>::difference_type num_canceled = 0;
    while (reqs_begin != reqs_end)
    {
        if ((RequestPtr(*reqs_begin))->cancel())
            ++num_canceled;
        ++reqs_begin;
    }
    return num_canceled;
}


template <typename RequestIterator>
RequestIterator poll_any(RequestIterator reqs_begin, RequestIterator reqs_end) {
    while (reqs_begin != reqs_end)
    {
        if ((RequestPtr(*reqs_begin))->poll())
            return reqs_begin;

        ++reqs_begin;
    }
    return reqs_end;
}

inline bool poll_any(RequestPtr req_array[], size_t count, size_t& index) {
    RequestPtr* res = poll_any(req_array, req_array + count);
    index = res - req_array;
    return res != (req_array + count);
}
}
#endif
